package com.droid.mvvmlib.base;

import android.os.Handler;
import android.os.Looper;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.lang.reflect.Type;
import java.util.concurrent.ConcurrentLinkedQueue;

import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;

/**
 * @author zyc0617
 * @since 2019/8/18 12:30
 */
public abstract class BaseModel<T>{

    protected Handler mUiHandler = new Handler(Looper.getMainLooper());
//    private BaseCacheData<T> mData;
    private CompositeDisposable compositeDisposable;
    protected ReferenceQueue<IBaseModeListener> mReferenceQueue;
    protected ConcurrentLinkedQueue<WeakReference<IBaseModeListener>> mWeakLinkArrayList;

    public BaseModel() {
        mReferenceQueue = new ReferenceQueue<>();
        mWeakLinkArrayList = new ConcurrentLinkedQueue<>();
        if (getCachedPreferenceKey() != null) {
//            mData = new BaseCacheData<T>()
        }
    }

    public void addSubscribe(Disposable disposable) {
        if (disposable == null) {
            return;
        }
        if (compositeDisposable == null) {
            compositeDisposable = new CompositeDisposable();
        }
        compositeDisposable.add(disposable);
    }

    public void cancel() {
        if (compositeDisposable != null && !compositeDisposable.isDisposed()) {
            compositeDisposable.isDisposed();
        }
    }

    /**
     * 注册
     * @param listener
     */
    public void register(IBaseModeListener listener) {
        if (listener == null) {
            return;
        }
        synchronized (this) {
            // 每次注销清理被系统回收的对象
            Reference<? extends IBaseModeListener> releaeReference = null;
            while ((releaeReference = mReferenceQueue.poll()) != null) {
                mWeakLinkArrayList.remove(releaeReference);
            }

            for (WeakReference<IBaseModeListener> weakListener : mWeakLinkArrayList) {
                IBaseModeListener listenerItem = weakListener.get();
                if (listenerItem == listener) {
                    return;
                }
            }
            WeakReference<IBaseModeListener> referenceListener = new WeakReference<>(listener, mReferenceQueue);
            mWeakLinkArrayList.add(referenceListener);

        }
    }

    /**
     * 注销
     * @param listener
     */
    public void unRegister(IBaseModeListener listener) {
        if (listener == null) {
            return;
        }
        synchronized (this) {
            for (WeakReference<IBaseModeListener> weakListener : mWeakLinkArrayList) {
                IBaseModeListener listenerItem = weakListener.get();
                if (listenerItem == listener) {
                    mWeakLinkArrayList.remove(weakListener);
                }
            }
        }
    }

    private boolean isNeedToUpdate() {
        return true;
    }

    protected void saveToPreference(T data){
//        mData = liveData;
//        mData.updateTimeMillis = System.currentTimeMillis();
//        BasePreferenceManager.getInstance(App.getInstance()).writeString(getCachedPreferenceKey(), GsonUtil.GsonString(data));
    }


    public abstract void refresh();

    protected abstract void load();

    protected abstract void notifyCacheData(T data);

    /**
     * 该model数据是否需要缓存，如果需要则返回缓存Key
     *
     * @return
     */
    protected String getCachedPreferenceKey() {
        return null;
    }

    /**
     * 缓存数据类型
     *
     * @return
     */
    protected Type getTClass() {
        return null;
    }

    /**
     * 该model数据是否存在apk预制的数据，如果则返回，默认没有
     *
     * @return
     */
    protected String getApkString() {
        return null;
    }

    public void getCachedDataAndLoad() {
//        if (getCachedPreferenceKey() != null) {
////            String cachedSaveData = BasePreferenceManager.getInstance(App.getInstance()).readString(getCachedPreferenceKey(), "");
//            String cachedSaveData = null;
//            if (StringUtils.isNotEmpty(cachedSaveData)) {
//                T saveData = GsonUtil.GsonToBean(cachedSaveData, getTClass());
//                if (saveData != null) {
//                    notifyCacheData(saveData);
//                    if (isNeedToUpdate()) {
//                        load();
//                    }
//                }
//                return;
//
//            }
//
//            if (StringUtils.isNotEmpty(getApkString())) {
//                notifyCacheData(GsonUtil.GsonToBean(getApkString(), getTClass()));
//            }
//        }
        load();
    }

    protected interface IBaseModeListener {

    }
}
